package memorytrace.requestmanagers

class RequestAllocEvents (allocEvents:java.util.ArrayList[memorytrace.domaine.AllocEvent]){

  
  /**
   * calcule la liste des allocations d'une valeur > size
   */
  def selectAllocEventsWhereSizeGreaterThan(size:Int)={
    
  }
  
  
  /**
   * calcule la liste des allocations d'une valeur < size
   */
  def selectAllocEventsWhereSizeLessThan(size:Int)={
    
  }
  
  
  /**
   * calcule la liste des pointeurs referencant une zone mémoire 
   * de taille size
   */
  def selectAllocEventsWhereSizeEqual(size:Int)={
    
  }
  
  /**
   * calcule la répartition des allocations en fonction de la 
   * distribution utilisé par l'allocateur sousdjacent
   */
  def groupeAllocEventsByChunkSizes(sizes:scala.collection.mutable.ListBuffer[Long])={
   
    var res = new Array[Long](sizes.size);
    var i=0
    res.foreach(x=>{res(i)=0;i+=1})
    
    var it=allocEvents.iterator()
    while(it.hasNext()){
      
      var current_event :memorytrace.domaine.AllocEvent = it.next()
      current_event match{
        
        case  m:memorytrace.domaine.EventMalloc  =>  insert(m.Size,res,sizes) 
        case  c:memorytrace.domaine.EventCalloc  =>  insert(c.Size*c.NbBlocs,res,sizes)
        case  r:memorytrace.domaine.EventRealloc =>  insert(r.Size,res,sizes)
        case  f:memorytrace.domaine.EventFree    =>    
      }
     
    } 
    res
  } 
  
  /**
   * 
   */
  private def insert(size:Long,table:Array[Long],sizes:scala.collection.mutable.ListBuffer[Long])={
    
    var i = -1
    val differences = sizes.map(x => 
      							{i+=1; 
    							(i,java.lang.Math.abs((size-x)))
    							}) 
	
    var (res_1,res_2) = differences(0)
	
    differences.foreach(t=> { if(t._2 < res_2){res_2=t._2;res_1=t._1}})
	
    table(res_1)+=1
  }

  /**
   * calcule la liste des pointeurs non liberés par le porgramme
   */
  def selectMemoryLeaks()={
    
  }
  
  
  
  
  /**
   * 
   */
  
  def getAllocSummary()={
   var (mallocs:Long,callocs:Long,reallocs:Long,frees:Long) = (0L,0L,0L,0L)
   
    var it=allocEvents.iterator()
    while(it.hasNext()){
      
      var current_event :memorytrace.domaine.AllocEvent = it.next()
    
      current_event match{
        
        case  m:memorytrace.domaine.EventMalloc  =>  mallocs+=1
        case  c:memorytrace.domaine.EventCalloc  =>  callocs+=1
        case  r:memorytrace.domaine.EventRealloc =>  reallocs+=1
        case  f:memorytrace.domaine.EventFree    =>  frees+=1  
      }
     
    }
    
    (mallocs,callocs,reallocs,frees)
  } 
  
  /**
   * permet de calculer la plus grosse allocation
   * la plus petite allocation
   * la moyenne des allocation
   * la somme des allocations
   * l'allocation la plus proche de la fin du tas
   * ...........................................
   */
  def aggregateEvents(op:(Long,Long) => Long, initVal:Long)={
    
    var res:Long = initVal
    var it=allocEvents.iterator()
    while(it.hasNext()){
      
      var current_event :memorytrace.domaine.AllocEvent = it.next()
    
      current_event match{
        
        case  m:memorytrace.domaine.EventMalloc  =>  res =op(res,m.Size)
        case  c:memorytrace.domaine.EventCalloc  =>  res =op(res,c.Size*c.NbBlocs)
        case  r:memorytrace.domaine.EventRealloc =>  res =op(res,r.Size)
        case  f:memorytrace.domaine.EventFree    =>    
      }
     
    } 
    res
  }
}